package com.wssnail.redis.utils;

import com.wssnail.redis.key.BaseKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.geo.*;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 熟透的蜗牛
 * @CreateTime: 2022-07-07 16:35
 * @Description: 工具类
 * @Version: 1.0
 */
@Slf4j
public class RedisUtil {

    private BaseKey prefix;

    private StringRedisTemplate stringRedisTemplate;

    private RedisTemplate<String, Object> redisTemplate;


    private static GenericJackson2JsonRedisSerializer redisObjectSerializer = new GenericJackson2JsonRedisSerializer();

    public RedisUtil(BaseKey prefix, StringRedisTemplate stringRedisTemplate, RedisTemplate<String, Object> redisTemplate) {
        this.prefix = prefix;
        this.stringRedisTemplate = stringRedisTemplate;
        RedisSerializer redisObjectSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setKeySerializer(new StringRedisSerializer()); // key的序列化类型
        redisTemplate.setValueSerializer(redisObjectSerializer); // value的序列化类型
        redisTemplate.setHashValueSerializer(redisObjectSerializer);
        redisTemplate.afterPropertiesSet();
        this.redisTemplate = redisTemplate;
    }


    /*
     * @description:缓存失效时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:43
     * @param key
     * @param time 单位秒
     * @return:
     * @return: boolean
     **/
    public boolean expire(String key, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            long rawTimeout = TimeoutUtils.toMillis(time, TimeUnit.SECONDS);
            try {
                return connection.pExpire(finalKey.getBytes(), rawTimeout);
            } catch (Exception e) {
                return connection.expire(finalKey.getBytes(), TimeoutUtils.toSeconds(rawTimeout, TimeUnit.SECONDS));
            }
        });
    }

    /*
     * @description:获取键值的过期时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:45
     * @param key
     * @return:
     * @return: long
     **/
    public long getExpire(String key) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.execute((RedisCallback<Long>) connection -> {
            try {
                return connection.pTtl(finalKey.getBytes(), TimeUnit.SECONDS);
            } catch (Exception e) {
                return connection.ttl(finalKey.getBytes(), TimeUnit.SECONDS);
            }
        });
    }

    /*
     * @description:判断键值是否存在
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:45
     * @param key
     * @return:
     * @return: boolean
     **/
    public boolean hasKey(String key) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.exists(finalKey.getBytes()));
    }

    // ============================Object=============================

    /*
     * @description:取值
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:46
     * @param key
     * @return:
     * @return: java.lang.Object
     **/
    public Object get(String key) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        Object value = redisTemplate.execute((RedisCallback<Object>) connection -> {
            byte[] temp = null;
            temp = connection.get(finalKey.getBytes());
            connection.close();
            return redisObjectSerializer.deserialize(temp);
        });
        return finalKey == null ? null : redisTemplate.opsForValue().get(finalKey);
    }

    /*
     * @description:设置键值，没有过期时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:47
     * @param key
     * @param value
     * @return:
     * @return: boolean
     **/
    public boolean set(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.execute((RedisCallback<Long>) connection -> {
                // redis info
                byte[] values = redisObjectSerializer.serialize(value);
                connection.set(finalKey.getBytes(), values);
                connection.close();
                return 1L;
            });
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("set-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:带过期时间，如果time小于0则键值不过期
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:47
     * @param key
     * @param value
     * @param time
     * @return:
     * @return: boolean
     **/
    public boolean set(String key, Object value, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            if (time > 0) {
                redisTemplate.execute((RedisCallback<Long>) connection -> {
                    // redis info
                    byte[] values = redisObjectSerializer.serialize(value);
                    connection.set(finalKey.getBytes(), values);
                    connection.expire(finalKey.getBytes(), time);
                    connection.close();
                    return 1L;
                });
            } else {
                set(finalKey, value);
            }
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("set-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:递增技术
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:48
     * @param key
     * @param delta 新增的步调
     * @return:
     * @return: long
     **/
    public long incr(String key, long delta) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.execute((RedisCallback<Long>) connection -> {
            return connection.incrBy(finalKey.getBytes(), delta);
        });
    }

    /*
     * @description:递减
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:49
     * @param key
     * @param delta
     * @return:
     * @return: long
     **/
    public long decr(String key, long delta) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }

        return redisTemplate.execute((RedisCallback<Long>) connection -> {

            return connection.incrBy(finalKey.getBytes(), -delta);
        });

    }

    /*
     * @description:删除缓存
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:50
     * @param key
     * @return:
     **/
    public void del(String... key) {
        List<String> keysList = new ArrayList<>();
        for (String kk : key) {
            String finalKey = String.format(prefix.getPrefix() + "%s", kk);
            keysList.add(finalKey);
        }
        if (keysList != null && keysList.size() > 0) {
            redisTemplate.delete(keysList);
        }
    }

    /*
     * @description:写入缓存，bit占用空间少
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:51
     * @param key
     * @param offset
     * @param isShow
     * @return:
     * @return: boolean
     **/
    public boolean setBit(String key, long offset, boolean isShow) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        boolean result = false;
        try {
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.setBit(finalKey, offset, isShow);
            result = true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("setBit-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
        return result;
    }

    /*
     * @description:获取内容
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:52
     * @param:
     * @param key
     * @param offset
     * @return:
     * @return: boolean
     **/
    public boolean getBit(String key, long offset) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        boolean result = false;
        try {
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            result = operations.getBit(finalKey, offset);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("getBit-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
        return result;
    }


    //===============================list=================================

    /*
     * @description:获取集合
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:52
     * @param key
     * @param start 起始
     * @param end 结束
     * @return:
     * @return: java.util.List<java.lang.Object>
     **/
    public List<Object> listGet(String key, long start, long end) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            return redisTemplate.opsForList().range(finalKey, start, end);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lGet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return null;
        }
    }

    /*
     * @description:获取集合长度
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:53
     * @param key
     * @return:
     * @return: long
     **/
    public long listGetListSize(String key) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            return redisTemplate.opsForList().size(finalKey);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lGetListSize-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return 0;
        }
    }

    /*
     * @description:根据下标获取元素
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:53
     * @param key
     * @param index
     * @return:
     * @return: java.lang.Object
     **/
    public Object listGetIndex(String key, long index) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            return redisTemplate.opsForList().index(finalKey, index);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lGetIndex-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return null;
        }
    }

    /*
     * @description:从右侧放入元素
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:54
     * @param:
     * @param key
     * @param value
     * @return:
     * @return: boolean
     **/
    public boolean listRightSet(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().rightPush(finalKey, value);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:右侧放入元素，并且有过期时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:54
     * @param key
     * @param value
     * @param time
     * @return:
     * @return: boolean
     **/
    public boolean listRightSet(String key, Object value, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().rightPush(finalKey, value);
            if (time > 0) expire(finalKey, time);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:放入集合
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:57
     * @param key
     * @param value
     * @return:
     * @return: boolean
     **/
    public boolean listRightSet(String key, List<Object> value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().rightPushAll(finalKey, value);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:带过期时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:58
     * @param key
     * @param value
     * @param time
     * @return:
     * @return: boolean
     **/
    public boolean listRightSet(String key, List<Object> value, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().rightPushAll(finalKey, value);
            if (time > 0) expire(finalKey, time);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    public boolean listLeftSet(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().leftPush(finalKey, value);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    public boolean listLeftSet(String key, Object value, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().leftPush(finalKey, value);
            if (time > 0) expire(finalKey, time);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:放入集合
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:57
     * @param key
     * @param value
     * @return:
     * @return: boolean
     **/
    public boolean listLeftSet(String key, List<Object> value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().leftPushAll(finalKey, value);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:带过期时间
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:58
     * @param key
     * @param value
     * @param time
     * @return:
     * @return: boolean
     **/
    public boolean listLeftSet(String key, List<Object> value, long time) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().leftPushAll(finalKey, value);
            if (time > 0) expire(finalKey, time);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:根据索引修改
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 16:59
     * @param key
     * @param index
     * @param value
     * @return:
     * @return: boolean
     **/
    public boolean listUpdateIndex(String key, long index, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            redisTemplate.opsForList().set(finalKey, index, value);
            return true;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lUpdateIndex-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return false;
        }
    }

    /*
     * @description:移除值为value的键值
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:31
     * @param key
     * @param count移除个数
     * @param value
     * @return:
     * @return: long
     **/
    public long listRemove(String key, long count, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        try {
            Long remove = redisTemplate.opsForList().remove(finalKey, count, value);
            return remove;
        } catch (Exception e) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            log.error("lRemove-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
            return 0;
        }
    }


    // ================================Map=================================

    /*
     * @description:存放hash
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:32
     * @param key
     * @param hashKey
     * @param value
     * @return:
     **/
    public void hmSet(String key, Object hashKey, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(finalKey, hashKey, value);
    }

    /*
     * @description:获取hash数据
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:32
     * @param key
     * @param hashKey
     * @return:
     * @return: java.lang.Object
     **/
    public Object hmGet(String key, Object hashKey) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(finalKey, hashKey);
    }


    // ================================set=================================

    /*
     * @description:集合添加元素
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:33
     * @param key
     * @param value
     * @return:
     **/
    public void add(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(finalKey, value);
    }

    /*
     * @description:集合获取元素
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:33
     * @param:
     * @param key
     * @return:
     * @return: java.util.Set<java.lang.Object>
     **/
    public Set<Object> setMembers(String key) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(finalKey);
    }

    /*
     * @description:添加有序集合
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:33
     * @param key
     * @param value
     * @param scoure
     * @return:
     **/
    public void zAdd(String key, Object value, double scoure) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(finalKey, value, scoure);
    }

    /*
     * @description:获取有序集合
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:34
     * @param key
     * @param scoure
     * @param scoure1
     * @return:
     * @return: java.util.Set<java.lang.Object>
     **/
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        redisTemplate.opsForValue();
        return zset.rangeByScore(finalKey, scoure, scoure1);
    }


    /*
     * @description:排序
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:34
     * @param key
     * @param value
     * @return:
     * @return: java.lang.Long
     **/
    public Long zRank(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rank(finalKey, value);
    }

    /*
     * @description:根据score排名
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:34
     * @param key
     * @param start
     * @param end
     * @return:
     * @return: java.util.Set<org.springframework.data.redis.core.ZSetOperations.TypedTuple<java.lang.Object>>
     **/
    public Set<ZSetOperations.TypedTuple<Object>> zRankWithScore(String key, long start, long end) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<Object>> ret = zset.rangeWithScores(finalKey, start, end);
        return ret;
    }

    /*
     * @description:添加 无score
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:36
     * @param key
     * @param value
     * @return:
     * @return: java.lang.Double
     **/
    public Double zSetScore(String key, Object value) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.score(finalKey, value);
    }

    /*
     * @description:添加 有score
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:36
     * @param key
     * @param value
     * @param scoure
     * @return:
     **/
    public void incrementScore(String key, Object value, double scoure) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.incrementScore(finalKey, value, scoure);
    }

    /*
     * @description:获取排名
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:37
     * @param key
     * @param start
     * @param end
     * @return:
     * @return: java.util.Set<org.springframework.data.redis.core.ZSetOperations.TypedTuple<java.lang.Object>>
     **/
    public Set<ZSetOperations.TypedTuple<Object>> reverseZRankWithScore(String key, long start, long end) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<Object>> ret = zset.reverseRangeByScoreWithScores(finalKey, start, end);
        return ret;
    }

    /*
     * @description:获取排名
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:37
     * @param key
     * @param start
     * @param end
     * @return:
     * @return: java.util.Set<org.springframework.data.redis.core.ZSetOperations.TypedTuple<java.lang.Object>>
     **/
    public Set<ZSetOperations.TypedTuple<Object>> reverseZRankWithRank(String key, long start, long end) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<Object>> ret = zset.reverseRangeWithScores(finalKey, start, end);
        return ret;
    }

    /*
     * @description: 添加经纬度  map.put("北京" ,new Point(116.405285 ,39.904989))
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:37
     * @param:
     * @param key
     * @param map
     * @return:
     * @return: java.lang.Long
     **/
    public Long addGeoPoint(String key, Map<Object, Point> map) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.opsForGeo().add(finalKey, map);
    }

    /*
     * @description:获取经纬度
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:38
     * @param:
     * @param key
     * @param member
     * @return:
     * @return: org.springframework.data.geo.Point
     **/
    public Point geoGetPoint(String key, String member) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        List<Point> lists = redisTemplate.opsForGeo().position(finalKey, member);
        return lists.get(0);
    }

    /*
     * @description: 获取两地的距离，单位km
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:39
     * @param:
     * @param key
     * @param srcMember
     * @param targetMember
     * @return:
     * @return: org.springframework.data.geo.Distance
     **/
    public Distance geoDistance(String key, String srcMember, String targetMember) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        Distance distance = redisTemplate.opsForGeo().distance(finalKey, srcMember, targetMember, Metrics.KILOMETERS);
        return distance;
    }

    /*
     * @description:获取地点半径 距离内的地点
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:40
     * @param key 键值
     * @param member 成成员
     * @param distance 距离
     * @return:
     * @return: org.springframework.data.geo.GeoResults
     **/
    public GeoResults geoRadiusByMember(String key, String member, double distance) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.opsForGeo().radius(finalKey, member, new Distance(distance, Metrics.KILOMETERS));
    }

    /*
     * @description:根据给定的经纬度，返回半径不超过指定距离的元素
     * @Author: 熟透的蜗牛
     * @date: 2022/7/7 17:41
     * @param:
     * @param key
     * @param circle
     * @param distance
     * @return:
     * @return: org.springframework.data.geo.GeoResults
     **/
    public GeoResults geoRadiusByCircle(String key, Circle circle, double distance) {
        String finalKey = String.format(prefix.getPrefix() + "%s", key);
        return redisTemplate.opsForGeo().radius(finalKey, circle, new Distance(distance, Metrics.KILOMETERS));
    }
}
